home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / mac / developm / source / mpwtools.cpt / misc src / Join.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-07-24  |  7.0 KB  |  303 lines

  1. /*
  2.     File:        Join.c
  3.  
  4.     Contains:    Join multipart postings into one
  5.                 Looks for (in order of preference)
  6.                     a) comp.binaries.mac format
  7.                     b) files generated by Unix "split"
  8.                     
  9.     Written by:    Sak Wathanasin
  10.                 178 Wainbody Ave South
  11.                 Coventry CV3 6BX
  12.                 UK
  13.     Phone:        +44 203 419996
  14.     E-mail:        sw@network-analysis-ltd.co.uk
  15.  
  16.     Copyright:    ⌐ 1990 by Network Analysis Ltd, all rights reserved.
  17.  
  18.     Change History:
  19.  
  20.       24/7/92    sw        "-" as file spec for stdin wasn't picked up
  21.        2/1/92    sw        Change CopyRest to allow for more than 1 "---" in the mailnote.
  22.       3/12/90    sw        Should look for "--- end" instead of just "---" to detect end
  23.                         of a part.
  24.       25/9/90    sw        Handle btoa'ed files
  25.       24/9/90    sw        Take care of blank line between (This... and the hex
  26.       11/8/90     sw        Base version
  27.  
  28.     To Do:
  29. */
  30.  
  31. #include <Types.h>
  32. #include <StdDef.h>
  33. #include <stdio.h>
  34. #include <Files.h>
  35. #include <errno.h>
  36. #include <StdLib.h>
  37. #include <String.h>
  38. #include <CursorCtl.h>
  39. #ifndef NIL
  40. #define NIL    (0L)
  41. #endif
  42.  
  43. #ifndef EOF
  44. #define EOF    (-1L)
  45. #endif
  46.  
  47. Boolean cbm =     true;              /* true if file is in comp.binaries.mac format */
  48. Boolean uu  =    false;            /* true if file is in uuencoded format */
  49. int        part, totalParts;        /* current part no, and total no of parts */
  50. int        binlen = 65;            /* length of a line of hexed binary */
  51.  
  52. /* Prototypes */
  53. void JoinFirst    (char *fileName);
  54. void Join        (char *fileName);
  55. void CopyRest    (FILE *fp);
  56. void SkipHdr    (FILE *infp);
  57.  
  58. main(int argc, char *argv[])
  59. {
  60.     char    **filelist;            /* list of files to process */
  61.     int        fileCount = 0;            /* no of files to process */    
  62.  
  63. #ifdef    MPW
  64.     InitCursorCtl(nil);
  65. #endif    MPW
  66.     argc--; argv++;
  67.     if ((filelist = (char **)calloc((size_t)argc, sizeof(Ptr))) == NULL) {
  68.         fprintf(stderr, "### Not enough memory\n");
  69.         exit(-1);
  70.     }
  71.     while (argc) {
  72.         if (argv[0][0] == '-') {
  73.             switch (argv[0][1]) {
  74.             case '\0':
  75.                 filelist[fileCount++] = "-";
  76.                 break;
  77.             case 'c':
  78.                 cbm = true;
  79.                 break;
  80.             case 'u':
  81.                 cbm = false;            /* in std Unix split format */
  82.                 break;
  83.             default:
  84.                 fprintf(stderr, "### Usage: join [-c] [-u] [files|ñ]\n");
  85.                 exit(-1);
  86.             }
  87.         }
  88.         else
  89.             filelist[fileCount++] = argv[0];
  90.         argc--; argv++;
  91.     }
  92.     /* at this point all files to process are in filelist */
  93.     part = 1;
  94.     totalParts = 0;
  95.     
  96.     JoinFirst(filelist[0]);
  97.     for (argc = 1; argc < fileCount; argc++) {
  98.         Join(filelist[argc]);
  99.     }
  100.     if (cbm && (part <= totalParts)) {
  101.         fprintf(stderr, "### Parts %d to %d missing\n", part, totalParts);
  102.         exit(-1);
  103.     }
  104.     exit(0);
  105. }
  106.  
  107. void JoinFirst (char *fileName)
  108. {
  109.     char    buffer[BUFSIZ];
  110.     char    *cp, *s;
  111.     FILE    *infp;
  112.     int        curPart, noParts;
  113.     
  114.     if (strcmp(fileName, "-") == 0)
  115.         infp = stdin;
  116.     else
  117.         infp = fopen(fileName, "r");
  118.     if (!infp) {
  119.         fprintf(stderr, "### Could not open file %s\n", fileName);
  120.         exit(-1);
  121.     }
  122.  
  123.     /* skip over news header lines etc. */
  124.     SkipHdr(infp);
  125.     
  126.     /* now scan to see if file is of c.b.m format */
  127.     while (cp = fgets(buffer, sizeof(buffer), infp)) {
  128.         if (buffer[0] == '[') break;
  129.         if (strncmp(buffer, "(This file must", 15) == 0) {
  130.             fputs(buffer, stdout);
  131.             /* Some binhex files have a blank line between the (This file...
  132.                line and the start of the hex
  133.             */
  134.             cp = fgets(buffer, sizeof(buffer), infp);
  135.             if (cp && buffer[0] == ':')
  136.                 fputs(buffer, stdout);
  137.             cbm = false;                /* not in c.b.m format */
  138.             uu = false;
  139.             break;
  140.         }
  141.         else if (strncmp(buffer, "begin ", 6) == 0) {    /* uuencoded file */
  142.             fputs(buffer, stdout);
  143.             cbm = false;
  144.             uu = true;
  145.             break;
  146.         }
  147.         else if (strncmp(buffer, "xbtoa Begin", 11) == 0) {    /* btoa file */
  148.             fputs(buffer, stdout);
  149.             cbm = false;
  150.             uu = false;
  151.             break;
  152.         }
  153.         else
  154.             fputs(buffer, stderr);        
  155.     }
  156.     
  157.     /* if we have a cbm file, get the total of parts */
  158.     if (cbm) {
  159.         /* look for "part n of m" */
  160.         s = strstr(buffer, "part");
  161.         (void) sscanf(s, "part %d of %d]", &curPart, &noParts);
  162.         fputs(buffer, stderr);
  163.         if (part != curPart) {
  164.             fprintf(stderr, "### Expecting part %d; got part %d\n", part, curPart);
  165.             exit(-1);
  166.         }
  167.         if (part == 1)
  168.             totalParts = noParts;
  169.     }
  170.     CopyRest(infp);
  171.     fclose(infp);
  172.     fflush(stdout);
  173.     fflush(stderr);
  174. }
  175.  
  176. /* process all the other files: they have no headers */
  177. void Join (char *fileName)
  178. {
  179.     char    buffer[BUFSIZ];
  180.     char    *cp;
  181.     FILE    *infp;
  182.     
  183.     infp = fopen(fileName, "r");
  184.     if (!infp) {
  185.         fprintf(stderr, "### Could not open file %s\n", fileName);
  186.         exit(-1);
  187.     }
  188.  
  189.     /* skip over news header lines etc. */
  190.     while (cp = fgets(buffer, sizeof(buffer), infp)) {
  191.         /* skip pass next blank line */
  192.         if (strlen(buffer) == 1) {
  193.             break;
  194.         }
  195.     }
  196.     CopyRest(infp);
  197.     fclose(infp);
  198.     fflush(stdout);
  199.     fflush(stderr);
  200. }
  201.  
  202. /* copy the rest of the file to stdout;
  203.    NB there may be more than 1 part contained in a single file;
  204.       users may either select all the msgs or combine all the parts together first.
  205. */
  206. void CopyRest(FILE *infp)
  207. {
  208.     char    *cp;
  209.     char    buffer[BUFSIZ];
  210.     int        len;
  211.     
  212.  
  213.     while (cp = fgets(buffer, sizeof(buffer), infp)) {
  214.         /* if we have a cbm file, we skip the little header */
  215.         if (cbm) {
  216.             /* if this is the 1st time through, skip up to a line starting (This... */
  217.             if (part == 1) {
  218.                 while(cp && strncmp(buffer, "(This file must", 15) != 0) {
  219.                     SpinCursor(-1);
  220.                     fputs(buffer, stderr);
  221.                     cp = fgets(buffer, sizeof(buffer), infp);
  222.                 }
  223.                 /* now buffer contains the line starting (This file...
  224.                    We need to copy all lines up to one starting with ":"
  225.                 */
  226.                 
  227.                 while (cp && buffer[0] != ':') {
  228.                     fputs(buffer, stdout);
  229.                     cp = fgets(buffer, sizeof(buffer), infp);
  230.                 }
  231.             }
  232.             else {
  233.             /* otherwise skip up to a line starting --- */
  234.                 while (cp && strncmp(buffer, "---", 3) != 0) {
  235.                     SpinCursor(-1);
  236.                     if (buffer[0] == '[')
  237.                         fputs(buffer, stderr);
  238.                     cp = fgets(buffer, sizeof(buffer), infp);
  239.                 }
  240.                 /* skip the "---" line */
  241.                 cp = fgets(buffer, sizeof(buffer), infp);
  242.             }
  243.         }
  244.             
  245.         /* now copy all the binary to std output
  246.            The following things terminate a "part"
  247.            1) a blank line, not followed by "end"
  248.            2) a line beginning "--- end"
  249.            3) a line beginning "Path"
  250.            4) a line beginning "From"
  251.            5) eof
  252.         */
  253.         while (cp &&
  254.                (len = strlen(buffer)) != 1 &&
  255.                strncmp(buffer, "--- end", 7) != 0 &&
  256.                strncmp(buffer, "Path", 4) != 0 &&
  257.                strncmp(buffer, "From", 4) != 0) {
  258.             SpinCursor(-1);
  259.             fputs(buffer, stdout);
  260.             cp = fgets(buffer, sizeof(buffer), infp);            
  261.         }
  262.         
  263.         /* work out how we got out of the loop */
  264.         if (len == 1 && uu) {                    /* a blank line */
  265.             /* check if the next line is "end" (uuencoded file) */
  266.             cp = fgets(buffer, sizeof(buffer), infp);
  267.             if (cp && strncmp(buffer, "end", 3) == 0) {
  268.                 fputc('\n', stdout);
  269.                 fputs(buffer, stdout);
  270.                 cp = fgets(buffer, sizeof(buffer), infp);
  271.             }
  272.             else
  273.                 SkipHdr(infp);
  274.         }
  275.         else if (cp && strncmp(buffer, "--- end of part", 15) == 0)
  276.             part++;
  277.         /* any other terminator means we are at the start of another part */
  278.         else {
  279.             part++;
  280.             if (cp != NULL)
  281.                 /* skip over news header lines etc. */
  282.                 SkipHdr(infp);
  283.         }
  284.     }
  285. }
  286.  
  287. /*    Function to skip mail/news headers
  288.  */
  289.  
  290. void SkipHdr (FILE *infp)
  291. {
  292.     char    *cp;
  293.     char    buffer[BUFSIZ];
  294.  
  295.     while (cp = fgets(buffer, sizeof(buffer), infp)) {
  296.         /* skip pass next blank line */
  297.         if (strlen(buffer) == 1) {
  298.             break;
  299.         }
  300.     }
  301.  
  302. }
  303.